/*****************************************************************************
*   Copyright (c) 2019 Thermo Fisher Scientific. All rights reserved.        *
*****************************************************************************/
/** @file
    @section DESCRIPTION
    Header file of Modbus, for UART of RTU.

    @author  ming.liu (ming.liu2@thermofisher.com)

    @version 1.0 

    @section LICENSE
    Use of the software source code and warranty disclaimers are
    identified in the Software Agreement associated herewith.

    @section GIT_PATH
    git@cnshf-cic-sw-bitbucket.apac.thermo.com:7999/vert/mcu.git
	

*/

#ifndef _MODBUS_RTU_H
#define _MODBUS_RTU_H
#include "FreeRTOS.h"
#include "mb_common.h"

#define U8  uint8_t
#define U16 uint16_t
#define U32 uint32_t
#define F32 float
	

#define MB_SLAVE_ADDRESS                					cmd_Buf[0]
#define MB_FUNCTION_CODE                					cmd_Buf[1]

#define FUNCT_CODE_0x03_START_ADDRESS           ((cmd_Buf[2] << 8) | cmd_Buf[3] )
#define FUNCT_CODE_0x03_QUANTITY_OF_REGS        ((cmd_Buf[4] << 8) | cmd_Buf[5] )

#define FUNCT_CODE_0x04_START_ADDRESS           ((cmd_Buf[2] << 8) | cmd_Buf[3] )
#define FUNCT_CODE_0x04_QUANTITY_OF_REGS        ((cmd_Buf[4] << 8) | cmd_Buf[5] )

#define FUNCT_CODE_0x06_REG_ADDRESS             ((cmd_Buf[2] << 8) | cmd_Buf[3] )
#define FUNCT_CODE_0x06_REG_VALUE               ((cmd_Buf[4] << 8) | cmd_Buf[5] )

#define FUNCT_CODE_0x10_START_ADDRESS           ((cmd_Buf[2] << 8) | cmd_Buf[3] )
#define FUNCT_CODE_0x10_QUANTITY_OF_REGS        ((cmd_Buf[4] << 8) | cmd_Buf[5] )
#define FUNCT_CODE_0x10_BYTE_COUNT              	cmd_Buf[6]
#define FUNCT_CODE_0x10_REGS_VALUE              	cmd_Buf[7]

#define FUNCT_CODE_0x17_READ_START_ADDRESS      ((cmd_Buf[2] << 8) | cmd_Buf[3] )
#define FUNCT_CODE_0x17_QUANTITY_TO_READ        ((cmd_Buf[4] << 8) | cmd_Buf[5] )
#define FUNCT_CODE_0x17_WRITE_START_ADDRESS     ((cmd_Buf[6] << 8) | cmd_Buf[7] )
#define FUNCT_CODE_0x17_QUANTITY_TO_WRITE       ((cmd_Buf[8] << 8) | cmd_Buf[9] )
#define FUNCT_CODE_0x17_WRITE_BYTE_COUNT        	cmd_Buf[10]
#define FUNCT_CODE_0x17_WRITE_REGS_VALUE        	cmd_Buf[11]

/* Modbus register addresses */
#define OUT_REGS_ADDR_START            0x0000
#define OUT_REGS_ADDR_END              0x01FF

#define INFO_REGS_ADDR_START           0x0200
#define INFO_REGS_ADDR_END             0x03FD

#define PWORD_REGS_ADDR_START          0x03FE
#define PWORD_REGS_ADDR_END            0x03FF

#define SPARE_REGS_ADDR_START          0x0400
#define SPARE_REGS_ADDR_END            0x05FF

#define IN_REGS_ADDR_START             0x0600
#define IN_REGS_ADDR_END               0x07FF

#define CAL_REGS_ADDR_START            0x0800
#define CAL_REGS_ADDR_END              0x09FF

#define FWUPDATE_REGS_ADDR_START       0x0A00
#define FWUPDATE_REGS_ADDR_END         0x0BFF

/* error codes for return communications */
#define ILLEGAL_FUNCTION         	0x01
#define ILLEGAL_DATA			 				0x02
#define CRC_ERROR			     				0x03

#define BAD_PACKET               	0x01
#define BAD_ADDRESS              	0x02
#define BAD_FLASH_WRITE          	0x03
#define BAD_STATE                	0x04

#define INVALID_FUNCTION            0X01
#define INVALID_REGISTER_ADDRESS    0X02
#define INVALID_REGISTER_VALUE      0X03
#define CANNOT_PROCESS              0X04


/* General defines, From val.h */
#define AMB_TEMP_OFFSET_MIN                -2.0
#define AMB_TEMP_OFFSET_MAX                2.0
#define AMB_TEMP_OFFSET_DEFAULT            0.0

#define USER_CAL_COEF_MIN                  0.5
#define USER_CAL_COEF_MAX                  2.0
#define USER_CAL_COEF_DEFAULT              1.0
/*------------------------------------------------------------------------------------*/



/* max read and write register count */
//#define MAX_RAM_WRITE_REGS			10  //this is too small on purpose
#define MAX_RAM_WRITE_REGS			66
#define MAX_RAM_READ_REGS				50   //we don't want this to make the struc bigger than necessary

/* Sub Types */
#define SUB_TYPE_Oxygen_Sensor  			0

typedef struct Dat_ramDb
{
  /* Common data to all input board. TBD: Modbus address */
    /* The strcuture is reserved for things that don't need to be read every second */
    /* Read/write registers. Address range: 0x0200 to 0x03FD */
    struct
    {
        /* Important: any changes to the info block should be reflected in 
		   functions build_info_block() and read_saved_info() */

        /* 125 is the maximum number of registers allowed by Modbus, See 
		   documenet: "FS Einstein internal Protocol.doc"*/
        /* This block is password protected */
        U16 board_type;

        /* application version number */
        U16 major_fw_ver;
        U16 minor_fw_ver;
        U16 maint_fw_ver;
        U16 build_fw_ver;

        /* bootloader version number */
        U16 major_bloader_ver;
        U16 minor_bloader_ver;
        U16 maint_bloader_ver;
        U16 build_bloader_ver;

        /* Module Serial number */
        U16 serial_number_char[8]; /* 16 char. alpha-numeric string */

        /* The sub type */
        U16 sub_type;

        /* Up time registers */
        U16 uptime_days;

        U8 module_serial_number_char[16];
        /* Turn usci_a0 communication watchdog ON/OFF */
        U16 uart_a0_comm_watchdog;

    } read_write_info;
	
	
	/* Address: 0x3FE */
    uint32_t password; /* password is used to restrict write access to 0x0200-0x03FD block (module info) */
	
	/* Read/write registers. Address range: 0x0800 to 0x09FF */
    struct
    {
        /* Initial Calibration details */
        U16 cal_fault;                  //bit 0: stop measurement error   bit 1: get user data error     2048
                                        //bit 2: set user data error      bit 3: save user data error   
                                        //bit4: start measurement error
				U16 cal_reserve;		//LM Add @2020-05-21 For align
			
        F32 userCalCoefficient;
        F32 factory_offset;
        F32 factory_span;
        F32 amb_temp_offset;
        F32 offset_conc1;
        F32 span_conc1;
        F32 integ_time;
        F32 offset_conc2;
        F32 span_conc2;
        F32 diag_mode;
        F32 lab_mode;
        F32 analog_switch;
				
				U16 external_reserve[MB_EXTERNAL_U16_LENGTH];  //2074
				F32 external_reserve2[MB_EXTERNAL_F32_LENGTH];
    } read_write_cal;
	
	
	/* input registers */
    union
    {
        uint16_t registers[MAX_RAM_WRITE_REGS];
        uint8_t  bytes[MAX_RAM_WRITE_REGS * sizeof(uint16_t)];
		

        struct //addr: 0x00-0x1ff
        {
					struct
          {
                /* A copy of Struct "state" exists in bootloader code */
                /* NB: When you modify struct "state" here make sure to 
																												modify struct "state"
                       the same way in database.h in bootloader */ 
                U16 BootloaderMode; /* 0=BL with invalid App, 1=BL with valid 
																				App, 2=App */
                /* fault registers */
								U16 fault_0;  //0x01
                U16 fault_1;  //0x02
								U16 fault_2;  //0x03
								U16 fault_3;  //0x04
                
                /* Up time registers */
                U16 uptime_days; //0x05
           } state;
					
					  U16 num_samples; //0x06
						U16 cal_status; 				/* reports back the calibration steps */
						F32 cal_result; 				/* reports back the calibration result */
					  F32 addr_analog_5V;   	//0x0A
					  F32 addr_digital_3V3; 	//0x0C
					  F32 addr_analog_3V3;
					  F32 addr_reserve_0;  		// 24V not sample
					  F32 addr_reserve_1;  		// ambient temp Not use
						
					  F32 o2_concentration;
						F32 lgd_concentration;
						F32 humid_conc;
						F32 temperature;
						F32 laser_current;
						F32 power_on_photodiode;
						F32 laser_temperature;
						F32 electronic_temperature;
						F32 control_scan;
						
						F32 addr_pumpPressure;
					  F32 addr_FlowPressure; 			// L/min
						
						F32 addr_temp_stinger;     //if TC broken-line, assignment 999 indicate
						F32 addr_temp_eject;
						F32 addr_temp_HotLine; 			//UMB
						F32 addr_temp_probeFilter;
						F32 addr_temp_probeblock;
					  F32 addr_board_temp; 				// LM61B air-conditional
					  F32 addr_temp_sampleIn;			// New add six channel temp @2020-07-09
					  F32 addr_temp_reserve_1;
					  
					  F32 addr_FlowRate;
					  
					  uint16_t addr_valStatus_rh; //local/remote
					  uint16_t addr_valStatus_Span; 
						uint16_t addr_valStatus_Zero;  //ON=2,OFF=0 , short-circuit=1  [ON:100mV, ]
						uint16_t addr_valStatus_Eject; 
						uint16_t addr_valStatus_Isolate; 
						uint16_t addr_valStatus_Blowback; 
						
						F32 addr_temp_RTD_RSV_1;			// Add by Teyu for 2-channels RTD @2020-07-24
					  F32 addr_temp_RTD_RSV_2;			// Add by Teyu for 2-channels RTD @2020-07-24

        } Midway_Board;
    } write;

    /* output registers */
    union
    {
        uint16_t registers[MAX_RAM_READ_REGS];
        uint8_t  bytes[MAX_RAM_READ_REGS * sizeof(uint16_t)];

        struct  //addr: 0x600 -0x7ff
        {
					
					U16 BootloadModeCmd; //1536
          U16 cal_action;
          F32 cal_target; /* Target value as entered by user */
					
					/* valve control */
					uint16_t addr_val_blowback_cnt;  
					uint16_t addr_blowback_ontime;		 
					uint16_t addr_blowback_offtime;		
					 
					uint16_t addr_reserve_3; //Valve Reset->Not use
					
					uint16_t addr_val_rh;
					uint16_t addr_val_span;
					uint16_t addr_val_zero;
					uint16_t addr_val_eject;
					uint16_t addr_val_iso;  //1549
					
					uint16_t addr_reserve_1; //blowback reserve

					uint16_t addr_air_power;
					uint16_t addr_tdlas_heater; //Always ON when power on  1551
					
					/* 6 channels temp control*/
					float addr_tarStinger_temp;
					float addr_tarEject_temp;
					float addr_tarUBM_temp;
					float addr_tarProbeFil_temp;
					float addr_tarPB_temp;  //1561
					float addr_tarSampleIn_temp;
					
					/* MbExtComm Config */  //ADDR:1563
					uint16_t addr_serialBaudRate;//[0-7:1200,2400,4800,9600,19200,38400,57600,115200]
					uint16_t addr_dataBits;			 //[0-1: 7bits, 8bits]  Not used for ccs platform NO-USE
					uint16_t addr_parity;				 //[0-2: none, even, odd]
					uint16_t addr_stopBits;			 //[0-1: 1-stop_bit, 2-stop_bit]

        } Midway_Board;

    } read;

} Dat_ramDb;




extern uint8_t cmd_Buf[];
extern Dat_ramDb dat_ram;
extern F32 tdlasData[];

void database_init(void);
void MB_execute_cmd(void);
void dat_initDatabase(void);

#endif
